<script setup lang="ts">
import { ref, onMounted } from "vue"
import { GUI } from 'three/addons/libs/lil-gui.module.min.js'

const domEl = ref(null)
let objectView = ref({
  options: 1,
  number: 1,
  boolean: true,
  hasMin: 11111,
  hasMax: 99,
  hasStep: 50,
  number1: 1,
  number2: 50,
  size: 'Medium',
  speed: 5,
  color1: '#AA00FF',
  color2: '#a0f',
  color3: 'rgb(170, 0, 255)',
  color4: 0xaa00ff,
  colorObject: { r: 0.667, g: 0, b: 1 },
  colorArray: [ 0.667, 0, 1 ],
  colorObject2: { r: 170, g: 0, b: 255 },
  colorArray2: [ 170, 0, 255 ],
  x: 1,
  y: 1,
  z: 1
})
const allKeys = []
for (const objectKey in objectView.value) {
  allKeys.push(objectKey)
}

const renderGui = () => {

  const gui = new GUI({ container: domEl.value, width: 310 })
  const object = {
    options: 1,
    number: 1,
    boolean: true,
    myFunction: function () {
      alert('hi')
    },
    // 数字和滑块
    hasMin: 1,
    hasMax: 99,
    hasStep: 50,
    // 具有最小值和最大值的控制器数量自动变为滑块。可以使用 缩写语法，用于同时定义它们
    number1: 1,
    number2: 50,
    // 下拉菜单 可以提供任意数据类型的数组创建下拉列表。如果提供一个对象，其键将用作选项的标签
    size: 'Medium',
    speed: 5,
    // 颜色 lil-gui 可识别多种格式的颜色：CSS 字符串、RGB 对象或十六进制值
    // 可以使用 addColor() 创建用于控制这些值的颜色选取器
    color1: '#AA00FF',
    color2: '#a0f',
    color3: 'rgb(170, 0, 255)',
    color4: 0xaa00ff,
    // RGB 对象和数组
    colorObject: { r: 0.667, g: 0, b: 1 },
    colorArray: [ 0.667, 0, 1 ],
    // RGB通道范围 RGB对象和数组的通道范围可以被覆盖，通过传递第三个参数到 addColor() 。如果颜色太亮，则可能需要将其设置为 255。
    colorObject2: { r: 170, g: 0, b: 255 },
    colorArray2: [ 170, 0, 255 ]
  }
  gui.add( object, 'number', 0, 100, 1 )
  gui.add( object, 'options', [ 1, 2, 3 ] )
  gui.add( object, 'boolean' )
  gui.add( object, 'myFunction' )

  gui.add( object, 'hasMin' ).min( 0 )
  gui.add( object, 'hasMax' ).max( 100 )
  gui.add( object, 'hasStep' ).step( 10 )

  gui.add( object, 'number1', 0, 1 ) // min, max
  gui.add( object, 'number2', 0, 100, 10 ) // min, max, step

  gui.add( object, 'size', [ 'Small', 'Medium', 'Large' ] )
  gui.add( object, 'speed', { Slow: 0.1, Normal: 1, Fast: 5 } )

  gui.addColor( object, 'color1' )
  gui.addColor( object, 'color2' )
  gui.addColor( object, 'color3' )
  gui.addColor( object, 'color4' )

  gui.addColor( object, 'colorObject' )
  gui.addColor( object, 'colorArray' )

  gui.addColor( object, 'colorObject2', 255 )
  gui.addColor( object, 'colorArray2', 255 )

  const folder = gui.addFolder( 'Position' )
  const position = {
    x: 1,
    y: 2,
    z: 3
  }
  folder.add( position, 'x' )
  folder.add( position, 'y' )
  folder.add( position, 'z' )

  gui.onChange( event => {
    console.log(event)
    if(Array.isArray(event.value)) {
      objectView.value[event.property].splice(0)
      objectView.value[event.property].push(...event.value)
    }else if(typeof event.value === 'object') {
      for (const eventValueKey in event.value) {
        objectView.value[event.property][eventValueKey] = event.value[eventValueKey]
      }
    }else {
      objectView.value[event.property] = event.value
    }
  })

}

onMounted(() => {
  renderGui()
})

</script>

<template>
  <div ref="domEl" class="domEl-class flex">
    <div class="font-bold px-5 w-1/3 leading-8">
      const object = {
        <p v-for="item in allKeys">
          &emsp;<span class="font-semibold">{{ item }}</span>: <span class="text-emerald-500">{{ objectView[item] }}</span>
        </p>
      }
    </div>
    <div class="font-bold w-1/3 leading-8">
      gui.add( object, 'number', 0, 100, 1 ) <br />
      gui.add( object, 'options', [ 1, 2, 3 ] ) <br />
      gui.add( object, 'boolean' ) <br />
      gui.add( object, 'myFunction' ) <br />

      gui.add( object, 'hasMin' ).min( 0 ) <br />
      gui.add( object, 'hasMax' ).max( 100 ) <br />
      gui.add( object, 'hasStep' ).step( 10 ) <br />

      gui.add( object, 'number1', 0, 1 ) // min, max <br />
      gui.add( object, 'number2', 0, 100, 10 ) // min, max, step <br />

      gui.add( object, 'size', [ 'Small', 'Medium', 'Large' ] ) <br />
      gui.add( object, 'speed', { Slow: 0.1, Normal: 1, Fast: 5 } ) <br />

      gui.addColor( obj, 'color1' ) <br />
      gui.addColor( obj, 'color2' ) <br />
      gui.addColor( obj, 'color3' ) <br />
      gui.addColor( obj, 'color4' ) <br />

      gui.addColor( object, 'colorObject' )
      gui.addColor( object, 'colorArray' )

      gui.addColor( object, 'colorObject2', 255 )
      gui.addColor( object, 'colorArray2', 255 )
    </div>
  </div>
</template>

<style scoped lang="scss">
.domEl-class {
  width: 100vw;
  height: 100vh;
  position: relative;
}
:deep(.lil-gui.root) {
  position: absolute;
  right: 0;
  top: 0;
}
</style>